/**
 * jquery.inline.js: Inline edit plugin for jquery.
 * 
 * Requirement:
 *     jQuery 1.2.0 or later.
 *     jquery form plugin 2.01 or later.
 *
 * @author  wuxi dot cn at gmail dot com
 * @version 0.1, 2007.12, wuxi
 */
var DEBUG=true;

(function ($) {

 $.fn.inline=function (url, options)
 {
	var defaults={
		success: null, // on post success callback function
		error: null, // post failed callback function
		loading_img: "loading.gif", // loading image
		autosize: false, // auto decide the size of editor
		edit: "click", // "click", "dblclick", "none"
		save: "ctrl+s", // "ctrl+s", "ctrl+enter", "enter", "none"
		cancel: "esc" // "esc", "none"
	};

	// initialize options
	var opt=$.extend(defaults, options);
	opt.save=opt.save.toLowerCase();
	opt.cancel=opt.cancel.toLowerCase();

	// define map of key-code to key-name
	var key_map={ 27: "esc", 13: "enter", 83: "s" };

	return this.each(function ()
	{
		var $me=$(this);

		// bind mouse events:
		$me.hover(function () { $(this).css("cursor", "pointer"); },
			function () { $(this).css("cursor", "auto"); });
		switch (opt.edit) {
		case "click":
			$me.click(on_edit);
			break;
		case "dblclick":
			$me.dblclick(on_edit);
			break;
		}

		// bind key events for editor
		var $editor=$(document.getElementsByName($me.attr("id"))[0]);
		$editor.keydown(function (k)
		{
			var key=(k.ctrlKey?'ctrl+':'')+key_map[k.which];

			if (key==opt.save) { // save action
				$(this).blur();
			}
			else if (key==opt.cancel) { // cancel action
				cancel();
			}
			else return; // bubble event to parent element

			return false; // cancel event bubble
		});
		$editor.blur(function ()
		{
			// save action
			save();
		});

		/* private functions: *********************/
		
		// trigger edit
		function on_edit()
		{
			$me.hide();
			$me.data=$editor.val();
			$editor.show().focus();
		};

		// save action
		function save()
		{
			var data=$editor.val();
			if ($me.data!=data) {
				$me.html("<img src='"+opt.loading_img+"' "+
					" alt='[L]' /> saving...");
				$.ajax({ type: "POST",
					url: url,
					dataType: "json", // return JSON
					data: $editor.fieldSerialize(),
					timeout: 60000, // 60 sec.
					error: on_error,
					success: on_success
				});
			}

			setTimeout(function () { $editor.hide(); $me.show(); }, 100);
		};

		// cancel action
		function cancel()
		{
			$editor.val($me.data).blur();
		};

		// submit failed
		function on_error()
		{
			if (opt.error)
				opt.error();
			else
				$me.html("error!");
		};

		// submit succeed
		function on_success(json)
		{
			// invoke user's callback function instead
			if (opt.success) {
				opt.success(json, $me[0], $editor[0]);
				return;
			}

			// on error
			if (json.type<0) {
				$me.html($me.data);
				$editor.val($me.data);
				alert("update failed.\n"+json.data);
				return;
			}

			// success
			$me.html(json.data);
			if (json.type==0) {
				$editor.val(json.data);
			}
			else if (json.type==1) {
				$editor.val(json.extra);
			}
		}

		return $me;
	});


	// debug if has firebug
	function debug(s)
	{
		if (typeof (DEBUG)=="undefined") return;

		if (DEBUG && window.console && window.console.log)
			window.console.log(s);
	};



 };

})(jQuery);


